package com.example.walkingtour.data;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class WTProvider extends ContentProvider {
	private static final String TAG = "WTProvider";

	private static final String AUTHORITY = "com.example.walkingtour.data.WTProvider";
	private static final String WT_BASE_PATH = "wtrecordings";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
			+ "/" + WT_BASE_PATH);

	public static final int RECORDINGS = 100;
	public static final int RECORDINGS_ID = 110;

	public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
			+ "/recording";
	public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
			+ "/recordings";

	private WTDatabase mDB;

	private static int numberOfRows; // number of rows in the (TourList) list
										// view

	public WTProvider() {
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		Log.d(TAG, "delete(...)");
		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase db = mDB.getWritableDatabase();
		int rowsAffected = 0;
		switch (uriType) {
		case RECORDINGS: // delete all
			rowsAffected = db.delete(WTDatabase.TABLE_RECORDINGS, selection,
					selectionArgs);
			break;
		case RECORDINGS_ID:
			String id = uri.getLastPathSegment();
			if (TextUtils.isEmpty(selection)) {
				rowsAffected = db.delete(WTDatabase.TABLE_RECORDINGS,
						WTDatabase.KEY_ROWID + "=" + id, null);
			} else {
				rowsAffected = db.delete(WTDatabase.TABLE_RECORDINGS, selection
						+ " and " + WTDatabase.KEY_ROWID + "=" + id,
						selectionArgs);
			}
			break;
		default:
			throw new IllegalArgumentException("Unknown or Invalid URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsAffected;
	}

	@Override
	public String getType(Uri uri) {
		Log.d(TAG, "getType(...)");
		int uriType = sURIMatcher.match(uri);
		switch (uriType) {
		case RECORDINGS:
			return CONTENT_TYPE;
		case RECORDINGS_ID:
			return CONTENT_ITEM_TYPE;
		default:
			return null;
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		Log.d(TAG, "insert(...)");
		int uriType = sURIMatcher.match(uri);
		if (uriType != RECORDINGS) {
			throw new IllegalArgumentException("Invalid URI for insert");
		}
		SQLiteDatabase db = mDB.getWritableDatabase();
		try {
			long newID = db.insertOrThrow(WTDatabase.TABLE_RECORDINGS, null,
					values);

			if (newID > 0) {
				Uri newUri = ContentUris.withAppendedId(uri, newID);
				getContext().getContentResolver().notifyChange(uri, null);
				numberOfRows++;
				return newUri;
			} else {
				throw new SQLException("Failed to insert row into " + uri);
			}
		} catch (SQLiteConstraintException e) {
			Log.i(TAG, "Ignoring constraint failure.");
		} catch (Exception e) {
			Log.i(TAG, e.getMessage());
		}

		return null;
	}

	@Override
	public boolean onCreate() {
		Log.d(TAG, "onCreate(...)");
		mDB = new WTDatabase(getContext());

		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		Log.d(TAG, "query(...)");
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		queryBuilder.setTables(WTDatabase.TABLE_RECORDINGS);

		int uriType = sURIMatcher.match(uri);
		switch (uriType) {
		case RECORDINGS_ID:
			// queryBuilder.appendWhere(WTDatabase.KEY_ROWID + "=" +
			// uri.getLastPathSegment());
			break;
		case RECORDINGS:
			// no filter (get all)
			break;
		default:
			throw new IllegalArgumentException("Unknown URI");
		}
		Cursor cursor = null;
		try {
			cursor = queryBuilder.query(mDB.getReadableDatabase(), projection,
					selection, selectionArgs, null, null, sortOrder);
			cursor.setNotificationUri(getContext().getContentResolver(), uri);

			numberOfRows = cursor.getCount();
		} catch (Exception e) {
			Log.d("Cursos error in WTProvider", e.getMessage().toString());
		}

		return cursor;
	}

	private static final UriMatcher sURIMatcher = new UriMatcher(
			UriMatcher.NO_MATCH);
	static {
		sURIMatcher.addURI(AUTHORITY, WT_BASE_PATH, RECORDINGS);
		sURIMatcher.addURI(AUTHORITY, WT_BASE_PATH + "/#", RECORDINGS_ID);
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		Log.d(TAG, "update(...)");
		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase db = mDB.getWritableDatabase();
		int rowsAffected = 0;

		switch (uriType) {
		case RECORDINGS_ID:
			String id = uri.getLastPathSegment();
			StringBuilder modSelection = new StringBuilder(WTDatabase.KEY_ROWID
					+ "=" + id);

			if (!TextUtils.isEmpty(selection))
				modSelection.append(" and " + selection);

			rowsAffected = db.update(WTDatabase.TABLE_RECORDINGS, values,
					modSelection.toString(), null);
			break;
		case RECORDINGS:
			rowsAffected = db.update(WTDatabase.TABLE_RECORDINGS, values,
					selection, null);
		default:
			throw new IllegalArgumentException("Unknown or Invalid URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsAffected;
	}

	/*
	 * Returns the number of rows on the (TourList) list view (this should be
	 * the same as number of database rows).
	 */
	public int getNumberOfRows() {
		return numberOfRows;
	}

}
